package com.wowangz.cms.user.api;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.util.WebUtils;

import com.wowangz.cms.common.pojo.AjaxDataEntity;
import com.wowangz.cms.common.select.BaseSelect;
import com.wowangz.cms.common.select.SelectFactory;
import com.wowangz.cms.common.utils.CommonCrypto;
import com.wowangz.cms.common.utils.DataCompare;
import com.wowangz.cms.common.utils.DataFormat;
import com.wowangz.cms.common.utils.SysConstant;
import com.wowangz.cms.syscore.InitEnvironment;
import com.wowangz.cms.syscore.IssTransactionContainer;
import com.wowangz.cms.syscore.api.BaseController;
import com.wowangz.cms.syscore.api.JSONFactory;
import com.wowangz.cms.syscore.api.UserContext;
import com.wowangz.cms.syscore.utils.JedisUtil;
import com.wowangz.cms.syscore.utils.LoadBaseDataConstants;
import com.wowangz.cms.syscore.utils.MessageResourcesUtils;
import com.wowangz.cms.syscore.utils.ServletUtils;
import com.wowangz.cms.user.pojo.Language;
import com.wowangz.cms.user.pojo.MenuAdmin;
import com.wowangz.cms.user.pojo.User;
import com.wowangz.cms.user.service.LoginService;
import com.wowangz.cms.user.service.MenuAdminService;

/**
 * Controller
 *运营管理端登录
 * @author yoyo
 */
@Scope("prototype")
@Controller
@SuppressWarnings("unchecked")
public class LoginController extends BaseController {

	private static Logger logger = LoggerFactory.getLogger(UserController.class);
	private String ERRORMESSAGE = "errorMessage";
	private final String ERRORPAGE = "redirect:/login.jsp";

	/**
	 * 语言
	 *
	 * @param request
	 * @param response
	 * @param model
	 */
	@RequestMapping(value = "/user/getlanguageList.json", method = { RequestMethod.GET, RequestMethod.POST })
	public void getlanguageList(HttpServletRequest request, HttpServletResponse response, Model model) {
		AjaxDataEntity ajaxDataEntity = new AjaxDataEntity();
		BaseSelect baseSelect = SelectFactory.createBaseSelect();
		try {
			LoginService loginService = (LoginService) IssTransactionContainer.getInstance(LoginService.class, false);
			List<Language> languageList = loginService.getlanguageList();
			System.out.println(languageList);
			for (Language language : languageList) {
				baseSelect.addOption(language.getLanguage(), language.getDescription());
			}
			ajaxDataEntity.setSelectInfo(baseSelect.getJSONSelectInfo());
			response.getWriter().write(JSONFactory.toJSONString(ajaxDataEntity, userContext));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @author HUANGYUAN
	 * @时间 2015年8月14日 下午4:15:17
	 * @param promptDays
	 * @param pswSaveDays
	 * @param userContext
	 * @return
	 * @描述 计算是否提醒用户改密码
	 */
	private void isPromptDays(long promptDays, long pswSaveDays, UserContext userContext, User loginUser) {
		Date pwdchangedate = loginUser.getPwdchangedate();
		if (pwdchangedate != null) {
			long pwddate = pwdchangedate.getTime();
			long current = new Date().getTime();
			// 得到上次改密码的时间与今天相隔多少天
			long time = (current - pwddate) / (24 * 60 * 60 * 1000);
			// 得到天数
			if (pswSaveDays - time > promptDays) {
				loginUser.setIsexpire(SysConstant.Boolean.FALSE);
				loginUser.setIsprompt(SysConstant.Boolean.FALSE);
			} else if ((pswSaveDays - time) <= promptDays && (pswSaveDays - time) > 0) {
				loginUser.setIsexpire(SysConstant.Boolean.FALSE);
				loginUser.setIsprompt(SysConstant.Boolean.TRUE);
			} else {
				loginUser.setIsexpire(SysConstant.Boolean.TRUE);
				loginUser.setIsprompt(SysConstant.Boolean.TRUE);
			}
			if (userContext.getLoginUser() != null) {
				if (pswSaveDays - time > promptDays) {
					userContext.getLoginUser().setIsexpire(SysConstant.Boolean.FALSE);
					userContext.getLoginUser().setIsprompt(SysConstant.Boolean.FALSE);
				} else if ((pswSaveDays - time) <= promptDays && (pswSaveDays - time) > 0) {
					userContext.getLoginUser().setIsexpire(SysConstant.Boolean.FALSE);
					userContext.getLoginUser().setIsprompt(SysConstant.Boolean.TRUE);
				} else {
					userContext.getLoginUser().setIsexpire(SysConstant.Boolean.TRUE);
					userContext.getLoginUser().setIsprompt(SysConstant.Boolean.TRUE);
				}
				userContext.getLoginUser().setDays((int) (pswSaveDays - time));
			}
		}
	}

	private boolean isValidate(Date errortime, Long minites) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			long errorDate = sdf.parse(sdf.format(errortime)).getTime();
			long current = sdf.parse(sdf.format(new Date())).getTime();
			if (current >= errorDate) {
				long error = errortime.getTime();
				long currenttime = new Date().getTime();
				long time = (currenttime - error) / (1000 * 60);
				if (time > minites) {
					return true;
				} else {
					return false;
				}
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 用户登录
	 *
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/user/login.web", method = { RequestMethod.GET, RequestMethod.POST })
	public String login(HttpServletRequest request, HttpServletResponse response, Model model) {
		MenuAdminService menuAdminService = (MenuAdminService)IssTransactionContainer.getInstance(MenuAdminService.class, false);
		User user = null;
		Date today = new Date();
		HttpSession session = request.getSession();
		String language = request.getParameter("language");
		try {
			session.setAttribute("com.iss.language", language);
			user = (User) ServletUtils.getParametersToBaseEntity(request, User.class);
			LoginService loginService = (LoginService) IssTransactionContainer.getInstance(LoginService.class, false);
			user.setStatusid(SysConstant.RecordStatus.VALID);
			User loginUser = loginService.findUserByLoginName(user);
			List<Object> list = InitEnvironment.getBaseDataCacheMap().get(LoadBaseDataConstants.PASSWORDPOLICY);
			Map<String, Object> passwordMap = list.size() > 0 ? (Map<String, Object>) list.get(0) : null;
			if (loginUser == null) {
				session.setAttribute(ERRORMESSAGE, MessageResourcesUtils.getMessage(request, "alertinfo.user.java.alert25"));
				return ERRORPAGE;
			}

			if (loginUser.getErrornumber() == Long.parseLong(passwordMap.get("accountlock").toString())) {
				if (!isValidate(loginUser.getErrortime(), Long.parseLong(passwordMap.get("accountlocktime").toString()))) {
					session.setAttribute(
							ERRORMESSAGE,
							MessageResourcesUtils.getMessage(request, "alertinfo.user.java.alert26")
									+ Long.parseLong(passwordMap.get("accountlocktime").toString())
									+ MessageResourcesUtils.getMessage(request, "alertinfo.user.java.alert27"));
					return ERRORPAGE;
				}
			}
			Long pswSaveDays = Long.parseLong(passwordMap.get("pswSaveDays").toString());
			Long promptDays = Long.parseLong(passwordMap.get("promptDays").toString());
			isPromptDays(promptDays, pswSaveDays, userContext, loginUser);
			String passwordSHA = CommonCrypto.encryptSHAEncoder(user.getPassword(), loginUser);
			if (!passwordSHA.equals(loginUser.getPassword())) {
				logger.info("用户密码输入错误");
				// 判断密码输入的错误的次数是否与设定错误的次数相等，如果相等则锁定账号
				if (loginUser.getErrornumber() < Long.parseLong(passwordMap.get("accountlock").toString())) {
					// 设置账号密码错误次数
					loginUser.setErrornumber(loginUser.getErrornumber() + 1);
					// 设置密码输入错误的时间
					loginUser.setErrortime(new Date());
					loginService.updateUserByLoginName(loginUser);
					// 将信息插入到缓存数据当中去
					JedisUtil.insertPublicDataObject(loginUser.getLoginname(), loginUser, JedisUtil.STORE_LOGINUSER);
					//User user2 = (User) JedisUtil.getPublicDataObject(loginUser.getLoginname(), User.class, JedisUtil.STORE_LOGINUSER);
				}
				session.setAttribute(ERRORMESSAGE, MessageResourcesUtils.getMessage(request, "alertinfo.user.java.alert25"));
				return ERRORPAGE;
			}
			loginUser = loginService.findUserByLoginName(user);
			if (loginUser.getCheckstatus().longValue() != SysConstant.CheckStatus.CHECKED) {
				logger.info("用户未复核");
				session.setAttribute(ERRORMESSAGE, MessageResourcesUtils.getMessage(request, "alertinfo.user.java.alert7"));
				return ERRORPAGE;
			}
			if (DataCompare.compareDate(today, loginUser.getValidstart()) == -1) {
				logger.info("用户有效期开始日错误，开始日：" + DataFormat.formatDate(loginUser.getValidstart(), DataFormat.DT_YYYY_MM_DD));
				session.setAttribute(
						ERRORMESSAGE,
						MessageResourcesUtils.getMessage(request, "alertinfo.user.java.alert2")
								+ DataFormat.formatDate(loginUser.getValidstart(), DataFormat.DT_YYYY_MM_DD));
				return ERRORPAGE;
			}

			if (DataCompare.compareDate(today, loginUser.getValidend()) == 1) {
				logger.info("用户有效期结束日错误，结束日：" + DataFormat.formatDate(loginUser.getValidend(), DataFormat.DT_YYYY_MM_DD));
				session.setAttribute(
						ERRORMESSAGE,
						MessageResourcesUtils.getMessage(request, "alertinfo.user.java.alert3")
								+ DataFormat.formatDate(loginUser.getValidend(), DataFormat.DT_YYYY_MM_DD));
				return ERRORPAGE;
			}

			userContext.setLoginDate(today);
			userContext.setLoginUser(loginUser);
			if (WebUtils.getSessionAttribute(request, "userContext") != null) {
				WebUtils.setSessionAttribute(request, "userContext", userContext);
			} else {
				WebUtils.setSessionAttribute(request, "userContext", userContext);
			}
			loginUser.setErrornumber(0l);
			userContext.setLoginUser(loginUser);
			loginUser.setErrortime(null);
			// 将信息插入到缓存数据当中去
			JedisUtil.insertPublicDataObject(loginUser.getLoginname(), loginUser, JedisUtil.STORE_LOGINUSER);
			userContext.setLoginUser(loginUser);
			System.out.println("SESSIONID:" + request.getSession().getId());
			loginService.updateUserByLoginName(loginUser);

			isPromptDays(promptDays, pswSaveDays, userContext, loginUser);
			if (loginUser.getPwdchangedate() == null || userContext.getLoginUser().getIsexpire() == SysConstant.Boolean.TRUE) {
				return "redirect:/login/first/intoResetPassword.json";
			}
			
			//根据登录人获得对应的职责菜单
			Long userid = loginUser.getId();
			Map<String,Object> hashMap = new HashMap<String, Object>();
			hashMap.put("userid", userid);
			hashMap.put("statusid", SysConstant.RecordStatus.VALID);
			hashMap.put("checkstatus", SysConstant.CheckStatus.CHECKED);
			List<MenuAdmin> list_menu = null;
			if(userid.longValue() == 1 || userid.longValue() == 2)
			{
				list_menu = menuAdminService.queryMenuAll(hashMap);
			}else
			{
				list_menu = menuAdminService.queryNormalMenu(hashMap);
			}
			List<MenuAdmin> headMenuList = splitHeadMenu(list_menu);
			model.addAttribute("userContext", userContext);
			model.addAttribute("headMenuList", headMenuList);
		} catch (Exception e) {
			e.printStackTrace();
			session.setAttribute(ERRORMESSAGE, MessageResourcesUtils.getMessage(request, "alertinfo.user.java.alert5"));
			return ERRORPAGE;
		}
		return "/main";
	}
	
	/**
	 * 组装menu 菜单根据顺序排好序
	 *
	 * @param list
	 */
	private List<MenuAdmin> splitHeadMenu(List<MenuAdmin> list) {
		final List<MenuAdmin> headMenu = new ArrayList<MenuAdmin>();
		// 记录每次循环上一次的菜单
		MenuAdmin latestMenu = null;
		for (final MenuAdmin menu : list) {
			// 模块大菜单
			if (menu.getMenulevel() == 1) {
				// menu.setParentMenu(menu);
				headMenu.add(menu);
			} else {
				// 如果menucode长度相同，则说明是同级菜单,父菜单相同
				if (menu.getMenucode().length() == latestMenu.getMenucode().length()) {
					menu.setParentMenu(latestMenu.getParentMenu());
					latestMenu.getParentMenu().getChildrenList().add(menu);
				}
				// 如果menucode比上一条记录长，说明是子菜单
				else if (menu.getMenucode().length() > latestMenu.getMenucode().length()) {
					menu.setParentMenu(latestMenu);
					latestMenu.getChildrenList().add(menu);
				}
				// 如果menucode短
				else if (menu.getMenucode().length() < latestMenu.getMenucode().length()) {
					// 判断层级
					final int level = count(latestMenu.getMenucode()) - count(menu.getMenucode());
					// 此菜单的父节点
					MenuAdmin tmp = latestMenu.getParentMenu();
					for (int i = 0; i < level; i++) {
						tmp = tmp.getParentMenu();
					}
					menu.setParentMenu(tmp);
					tmp.getChildrenList().add(menu);
				}
			}

			latestMenu = menu;
		}
		return headMenu;
	}
	
	private static int count(String str) {
		int res = 0;
		final String[] temp = str.split("");
		for (final String element : temp) {
			// 如果字母等于c
			if (element.equals("-")) {
				// 计数器加一
				res++;
			}
		}
		return res;
	}

	@RequestMapping(value = "/login/userLogout.web", method = {RequestMethod.POST,RequestMethod.GET})
	public void userLogout(HttpServletRequest arg0, HttpServletResponse arg1, Model model) {
		AjaxDataEntity entity = new AjaxDataEntity();
		UserContext userContext = null;
		try {
			if (WebUtils.getSessionAttribute(arg0, "userContext") != null) {
				userContext = (UserContext) WebUtils.getSessionAttribute(arg0, "userContext");
				User sysUser = userContext.getLoginUser();
				model.addAttribute("sysUser", sysUser);
			}
			WebUtils.setSessionAttribute(arg0, "userContext", null);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				arg1.getWriter().write(JSONFactory.toJSONString(entity, getUserContext()));
			} catch (final IOException e) {
				e.printStackTrace();
			}
		}
	}
}
